/*
 * ConfigModel.java
 * business
 *
 * Created by ChenTao on 2017/1/17.
 *
 * Copyright (c) 2017年 yidiandao. All rights reserved.
 */

package com.yidiandao.business.data.model;

import android.text.TextUtils;

import com.yidiandao.business.constant.Preferences;
import com.yidiandao.business.constant.Urls;
import com.yidiandao.business.data.event.UnZipBottomBarIconFinishEvent;
import com.yidiandao.business.data.net.BaseRequest;
import com.yidiandao.business.data.net.DownloadListener;
import com.yidiandao.business.data.net.NetBiz;
import com.yidiandao.business.data.net.NetListener;
import com.yidiandao.business.data.net.exception.BizErrorInfo;
import com.yidiandao.business.data.net.exception.NetErrorInfo;
import com.yidiandao.business.data.request.ConfigRequest;
import com.yidiandao.business.data.request.DownloadBottomBarRequest;
import com.yidiandao.business.data.response.BottomBarUpdateResponse;
import com.yidiandao.business.data.response.ConfigResponse;
import com.yidiandao.business.utils.FileUtils;
import com.yidiandao.business.utils.LogUtils;
import com.yidiandao.business.utils.PreferenceUtils;
import com.yidiandao.business.utils.UIUtils;
import com.yidiandao.business.utils.ZipUtils;

import net.lingala.zip4j.exception.ZipException;

import org.greenrobot.eventbus.EventBus;

import java.io.File;

/**
 * 配置接口
 */
public class ConfigModel implements IConfigModel {

    // 保存BottomBar zip文件的地址
    public static final String BOTTOM_MENU_DIR_NAME =
            UIUtils.getContext().getCacheDir().getAbsolutePath();

    // 服务器给的文件目录  dir/2X  或者 dir/3X
    /**
     * 解压的目录名称
     */
    public static final String BOTTOM_MENU_UNZIP_DIR_NAME = "bottom_menu";

    public static final String ICON_DIR = "3X";
    /**
     * 下载后，保存的Zip文件的名称
     */
    private static final String BOTTOM_MENU_SAVED_FILE_NAME = "bottom_menu.zip";

    private NetBiz mNetBiz = new NetBiz();

    @Override
    public void getBottomBarUpdate(final String tag) {

        BaseRequest request = new BaseRequest();
        request.setUrl(Urls.GET_BOTTOM_BAR_UPDATE);
        request.setTag(tag);

        mNetBiz.sendGetRequest(request, BottomBarUpdateResponse.class,
                new NetListener<BottomBarUpdateResponse>() {
                    @Override
                    public void onSuccess(BottomBarUpdateResponse response) {
                        BottomBarUpdateResponse.Data data = response.getData();
                        String serverMD5 = data.getMd5();
                        String zipFileDownloadUrl = data.getZipFile();

                        // 本地的zip文件
                        File localFile = new File(BOTTOM_MENU_DIR_NAME, BOTTOM_MENU_SAVED_FILE_NAME);

                        if (localFile.exists() && checkFileMD5(serverMD5, localFile)) {
                            // 如果本地文件存在，并且本地的文件校验成功，说明文件已经下载，不再需要重复下载
                            LogUtils.d("不再需要下载，BottomBar更新包已经存在");
                            File file = new File(BOTTOM_MENU_DIR_NAME, BOTTOM_MENU_UNZIP_DIR_NAME);
                            if (!file.exists() || file.length() == 0) {
                                // 文件夹不存在或者文件的的长度为0，需要解压
                                unzipBottomBarUpdateFile(new File(BOTTOM_MENU_DIR_NAME, BOTTOM_MENU_SAVED_FILE_NAME));
                            }
                        } else {
                            // 校验不成功，或者文件不存在，删除本地的zip文件
                            // 需要重新下载更新的zip文件
                            LogUtils.d("下载BottomBar更新包");
                            FileUtils.deleteFile(localFile);
                            downloadBottomBarUpdateFile(serverMD5, zipFileDownloadUrl, localFile.getParent(), localFile.getName(), tag);
                        }
                    }

                    @Override
                    public boolean onError(NetErrorInfo netErrorInfo) {
                        return false;
                    }

                    @Override
                    public boolean onFailed(BizErrorInfo bizErrorInfo) {
                        return false;
                    }

                    @Override
                    public void onFinal() {
                    }
                });
    }

    @Override
    public boolean isGuideShowed() {
        return PreferenceUtils.getBoolean(UIUtils.getContext(), Preferences.GUIDE_IS_SHOW, true);
    }

    @Override
    public String getCurrentCity() {
        return PreferenceUtils.getString(UIUtils.getContext(), Preferences.CITY, true);
    }

    @Override
    public void setOpenAppCount() {
        //记录app打开次数
        int appUserCount = PreferenceUtils.getInt(UIUtils.getContext(), Preferences.NUMBER, true);
        if (appUserCount == PreferenceUtils.INT_DEFAULT) {
            appUserCount = 0;
        }
        appUserCount++;
        PreferenceUtils.setInt(UIUtils.getContext(), Preferences.NUMBER, appUserCount, true);
    }

    /**
     * 校验文件的MD5与服务器给的MD5是否一致
     *
     * @param serverFileMD5 服务器给的文件的MD5值
     * @param checkFile     需要检查的文件
     * @return 两者的MD5值是否相同
     */
    private boolean checkFileMD5(String serverFileMD5, File checkFile) {
        return !TextUtils.isEmpty(serverFileMD5)
                && serverFileMD5.equals(FileUtils.fileToMD5(checkFile.getAbsolutePath()));
    }

    private void downloadBottomBarUpdateFile(final String serverFileMD5, String downloadUrl, String dirName, final String fileName, String tag) {
        if (downloadUrl == null) {
            return;
        }
        DownloadBottomBarRequest request = new DownloadBottomBarRequest();
        request.setTag(tag);
        request.setUrl(downloadUrl);

        mNetBiz.downloadFile(request, dirName, fileName, new DownloadListener() {
            @Override
            public void onSuccess(File file) {
                LogUtils.d("---> 皮肤更新包下载成功");
                if (checkFileMD5(serverFileMD5, file)) {
                    // 验证文件的md5,避免因文件下载“失败”错误解压
                    LogUtils.d("---> 皮肤更新包MD5验证成功");
                    unzipBottomBarUpdateFile(file);
                } else {
                    // 校验不成功
                    FileUtils.deleteFile(file);
                }
            }

            @Override
            public boolean onError(NetErrorInfo netErrorInfo) {
                LogUtils.e("---> 下载皮肤更新包失败 ");
                return false;
            }

            @Override
            public void onFinal() {
            }
        });
    }

    /**
     * 解压文件
     */
    private void unzipBottomBarUpdateFile(File zipFile) {
        File zipDir = new File(zipFile.getParent(), BOTTOM_MENU_UNZIP_DIR_NAME);
        try {
            ZipUtils.unzip(zipFile.getAbsolutePath(), zipDir.getAbsolutePath());
//            postUnZipBottomBarIconFinishEvent();
            LogUtils.d("皮肤更新包解压成功");
        } catch (ZipException e) {
            LogUtils.e("皮肤更新包解压失败");
            // 删除整个文件夹
            FileUtils.deleteFile(zipDir);
        }
    }

    public void postUnZipBottomBarIconFinishEvent() {
        EventBus.getDefault().post(new UnZipBottomBarIconFinishEvent());
    }

    @Override
    public void getConfig(String tag) {
        ConfigRequest request = new ConfigRequest();
        request.setUrl(Urls.CONFIG);
        request.setTag(tag);
        request.setVersion(PreferenceUtils.getString(UIUtils.getContext(), Preferences.SERVER_CONFIG_VERSION, true));

        mNetBiz.sendGetRequest(request, ConfigResponse.class, new NetListener<ConfigResponse>() {
            @Override
            public void onSuccess(ConfigResponse response) {

                ConfigResponse.Data data = response.getData();

                // 服务器配置文件版本
                PreferenceUtils.setString(UIUtils.getContext(), Preferences.SERVER_CONFIG_VERSION,
                        data.getVersion(), true);

                // 电话号码正则,需要判断升级的配置中判断是否有该字段
                String mobilePattern = data.getMobilePattern();
                if (mobilePattern != null) {
                    PreferenceUtils.setString(UIUtils.getContext(), Preferences.MOBILE_PATTERN,
                            mobilePattern, true);
                }
            }

            @Override
            public boolean onError(NetErrorInfo netErrorInfo) {
                return false;
            }

            @Override
            public boolean onFailed(BizErrorInfo bizErrorInfo) {
                return false;
            }

            @Override
            public void onFinal() {
            }
        });
    }
}
